package com.ly.user_system.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.ly.user_system.base.BaseUserDetails;
import com.ly.user_system.dto.BaseSysMenuDTO;
import com.ly.user_system.dto.BaseSysPermDTO;
import com.ly.user_system.entity.BaseSysMenu;
import com.ly.user_system.entity.BaseSysRoleMenu;
import com.ly.user_system.entity.BaseSysUserRole;
import com.ly.user_system.service.BaseSysMenuService;
import com.ly.user_system.service.BaseSysPermsService;
import com.ly.user_system.service.BaseSysRoleMenuService;
import com.ly.user_system.service.BaseSysUserRoleService;
import com.ly.user_system.utils.ListUtil;
import com.ly.user_system.utils.UserContextUtil;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author HASEE
 */
@Service
@RequiredArgsConstructor
public class BaseSysPermsServiceImpl implements BaseSysPermsService {
    @Resource
    private BaseSysUserRoleService userRoleService;

    @Resource
    private BaseSysRoleMenuService roleMenuService;

    @Resource
    private BaseSysMenuService menuService;

    @Override
    public List<String> getPerms(Long id) {
        return getPemByRoles(getRolesByUserId(id),!id.equals(1L));
    }



    @Override
    public List<String> getPemByRoles(List<Long> roleIdList,Boolean commonUserFlag) {
        List<Long> menuIds = roleMenuService.listEntityWithFunction(queryWrapper -> queryWrapper.in(commonUserFlag,BaseSysRoleMenu::getRoleId, roleIdList), BaseSysRoleMenu::getMenuId);
        if (CollUtil.isEmpty(menuIds)) {
            return new ArrayList<>();
        }
        return menuService
                .listEntityWithFunction(queryWrapper -> queryWrapper.in(commonUserFlag,BaseSysMenu::getId, menuIds), baseSysMenu -> StrUtil.isNotBlank(baseSysMenu.getPerms())?Arrays.asList(baseSysMenu.getPerms().split(",")):new ArrayList<String>())
                .stream()
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    }

    @Override
    public List<Long> getRolesByUserId(Long uerId) {
        return userRoleService.listEntityWithFunction(queryWrapper -> queryWrapper.eq(BaseSysUserRole::getUserId, uerId), BaseSysUserRole::getRoleId);
    }

    @Override
    public BaseSysPermDTO listSelfPerm() {
        BaseUserDetails userDetails = (BaseUserDetails) UserContextUtil.getUserContext().getPrincipal();
        List<Long> rolesByUserId = getRolesByUserId(userDetails.getUserId());
        List<Long> menuIds = roleMenuService.listEntityWithFunction(roleMenuQuery -> roleMenuQuery.in(CollUtil.isNotEmpty(rolesByUserId),BaseSysRoleMenu::getRoleId, rolesByUserId), BaseSysRoleMenu::getMenuId);
        // 列表转树
        List<BaseSysMenuDTO> tree = menuService.listDtoWithConsumer(menuQuery -> menuQuery.in(CollUtil.isNotEmpty(menuIds),BaseSysMenu::getId, menuIds),dtoList-> ListUtil.listToTree(dtoList, BaseSysMenuDTO::getId, BaseSysMenuDTO::getParentId, BaseSysMenuDTO::setChildList));

        return BaseSysPermDTO.builder()
                .menus(tree)
                .perms(userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
                .build();

    }

}
